#include <eiklbx.h>
#include <Function.h>
#include <euserhl.h>
#include <eiklbi.h>
#include <aknutils.h>
#include <akniconarray.h>
#include "ActiveTarget.h"
#include "DrawUtils.h"

#include <aknlists.h>

#ifndef __CSINGAPORELISTBOX__
#define __CSINGAPORELISTBOX__


class CSingaporeBusListBox2 : public CAknDoubleGraphicStyleListBox
	{
public:
	mutable TTime iTimePreviousFrame;
	mutable TInt64 iMinFrameDelay;
	mutable TInt64 iMaxFrameTime;
	mutable TInt iAllocMem;  // Amount allocated
	mutable TInt iHeapSize;  // Current heap size
	mutable TInt iLimitHeapSize;  // Max heap size
	mutable TInt iMaxTimeFrame;
	mutable TInt iAccumulatedTimeFrame;
	mutable TInt iLastTimeFrame;
	mutable TInt iCountFrames;
	CSingaporeBusListBox2();
	virtual void Draw(const TRect& aRect) const;
	};

class CSingaporeBusListBox;

class CSingaporeBusListBoxItemDrawer : public CListItemDrawer
	{
	LManagedHandle<RTimer> iRedrawTimer;
	void Redraw();
	mutable TTime iTimePreviousCurrentItemChange;
	mutable TInt iPreviousCurrentItem;
	
	CSingaporeBusListBox* iListBox;
	LManagedPtr< CAknIconArray > iIconArray;
    LManagedPtr< scalp::CFunction< void(const CSingaporeBusListBoxItemDrawer*, TInt, const TRect&, TBool, TBool, TBool, TBool )> > iDrawItemFun;
public:
	LManagedPtr< scalp::CActiveTarget > iRedrawTarget;
	mutable TBool iScrollingOn;
	CSingaporeBusListBox* ListBox() const;
	void SetIconArray(CAknIconArray* aIconArray);
	const CAknIconArray* IconArray() const;
    CSingaporeBusListBoxItemDrawer(CSingaporeBusListBox* aListBox, scalp::CFunction< void(const CSingaporeBusListBoxItemDrawer*, TInt, const TRect&, TBool, TBool, TBool, TBool )>* aFun);
	void ScheduleRedrawL(TTimeIntervalMicroSeconds32 anInterval);
	const TTime& TimePreviousCurrentItemChange() const;
	void DrawActualItem(TInt aIndex, const TRect& aActualItemRect,
			TBool aItemIsCurrent, TBool aViewIsEmphasized, TBool aViewIsDimmed, 
			TBool aItemIsSelected) const;
	};

class CSingaporeBusListBoxModel : public CAknFilteredTextListBoxModel// CAknFilteredTextListBoxModel is required instead of MListBoxModel because HandlePopupFindSizeChanged crashes KERN-EXEC 3 with MListBoxModel ...
	{
	mutable TInt iPrevNumberOfItems;
	CSingaporeBusListBox* iListBox;
public:
	MListBoxModel* iListBoxModel;
	CSingaporeBusListBoxModel(CSingaporeBusListBox* aListBox, MListBoxModel* aListBoxModel);
	TInt NumberOfItems() const;
	};

class CFillerControl : public CCoeControl
	{
public:
	virtual void Draw(const TRect& aRect) const;
	};

class CSingaporeBusListBox : public CEikListBox
	{
	const CCoeControl* iParent;
	TPoint iDragOrigin, iDraggingOffset, iAccumulatedDragging;
	TBool iDragging;
	LManagedPtr<CPeriodic> iDraggingTimer;
	TPointerEvent iLastEvent;
	
	mutable TTime iTimePreviousFrame;
	mutable TInt64 iMinFrameDelay;
	mutable TInt64 iMaxFrameTime;
public:
	
	void InvalidateCurrentItemL();
	mutable TInt iAllocMem;  // Amount allocated
	mutable TInt iHeapSize;  // Current heap size
	mutable TInt iLimitHeapSize;  // Max heap size
	
	mutable TInt iMaxTimeFrame;
	mutable TInt iAccumulatedTimeFrame;
	mutable TInt iLastTimeFrame;
	mutable TInt iCountFrames;
	TBool iFlicking;
	TBool iPenDown;
	void ResetDragging();
	TInt DraggingCallback();
	TBool Dragging() const;
	TPoint DraggingOffset() const;
	CFillerControl* iFillerControl;
	void ConstructL(scalp::CFunction< void(const CSingaporeBusListBoxItemDrawer*, TInt, const TRect&, TBool, TBool, TBool, TBool )>* aFun, MListBoxModel* aListBoxModel, const CCoeControl* aParent, TInt aFlags = 0);
	CSingaporeBusListBoxItemDrawer* ItemDrawer() const;
	virtual void Draw(const TRect& aRect) const;
	void HandlePointerEventL(const TPointerEvent& aPointerEvent);
	void ReportListBoxEventL( MEikListBoxObserver::TListBoxEvent aEvent );
	};

#endif //__CSINGAPORELISTBOX__
